﻿using System;
using System.Security.Cryptography;
using System.Text;

namespace Common.Password
{
    public class PasswordHash
    {
        /// <summary>
        /// Gib den Hashcode zum übergebenen Passwort zurück
        /// </summary>
        /// <param name="password">Passwort von dem der Hashcode ermittelt werden soll.</param>
        /// <returns>Hashcode des übergebenen Passwortes</returns>
        public static string GetPasswordHash(string password)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            // create a byte array by Hashing the Text Box Value,
            byte[] encodedBytes = md5.ComputeHash(ASCIIEncoding.Default.GetBytes(password));

            //Convert the Bytes to hexadecimal string from class BitConverter
            return BitConverter.ToString(encodedBytes);
        }

        /// <summary>
        /// Hashen des Passwortes inkl. des Salt wertes so oft man möchte mit Hilfe des hashCounts
        /// </summary>
        /// <param name="password">Das Passwort was gehasht werden soll</param>
        /// <param name="salt">der Salt der zum Hashen verwendet werden soll</param>
        /// <param name="hashCount">Wie oft das ganze gehasht werden soll</param>
        /// <returns>Password Hash</returns>
        public static string GetPasswordHash(string password, string salt, int hashCount)
        {
            string pwHash = password;
            //Das PAsswort mehrfach hashen um eine höhere Sicherheit gewähren zu können.
            for (int i = 0; i < hashCount; i++)
            {
                pwHash = GetPasswordHash(string.Format("{0}{1}", pwHash, salt));
            }

            return pwHash;
        }

        
        /// <summary>
        /// Erstellt einen Randomstring in der übergebenen Länge
        /// </summary>
        /// <param name="size">Size of the string</param>
        /// <param name="lowerCase">If true, generate lowercase string</param>
        /// <returns>Random string</returns>
        public static string GetRandomString(int size, bool lowerCase)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;

            for (int i = 0; i < size; i++)
            {
                int strOrInt = random.Next(144);

                //Entscheiden ob eine Zahl oder ein String zum Pw hinzugefügt werden soll.
                if (strOrInt % 2 == 0)
                {
                    //Hinzufügen einer Zufallszahl
                    builder.Append(random.Next(0, 10).ToString());
                }
                else
                {
                    //Hinzufügen eines Randomchars.
                    ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));

                    //Einfach noch per "zufall" kleine Buchstaben in den Randomstring einbauen.
                    if (strOrInt % 3 == 0)
                    {
                        builder.Append(ch.ToString().ToLower());    
                    }
                    else
                    {
                        builder.Append(ch);    
                    }
                }
            }

            if (lowerCase)
            {
                return builder.ToString().ToLower();
            }

            return builder.ToString();
        }
    }
}
